# from BaslerCam.BaslerCam_class import BaslerCam # qdzs
import queue


# from sengo_common.myMVSCam import MVSCam as SimCam


# from camera.mvs_line_camera.MVSCam_class import MVSCam as MVSLineCam
# open() close() getFrame()


class SafeCam:  # 多次取流， 重连
    def __init__(self, cls, ip0=None, triggermode='off',total_step=15):
        self.ip0 = ip0
        self.cam = None
        self.cls = cls  # 相机句柄
        self.triggermode = triggermode
        if ip0 is not None:
            self.open(ip0, triggermode, self.get_frame_callback()) # 打开相机，

        self.imgs_queue = queue.Queue(maxsize=1)
        # self.current_img = None
        self.hit_int = 0
        self.numb = 0

        # if ip0 == '169.254.14.111': # 左
        #     self.total_step = 15
        # elif ip0 == '169.254.112.101': # 右
        #     self.total_step = 9
        # elif not ip0.split('.') == 4: # sim camere
        #     self.total_step = 15
        # else:
        #     raise Exception('相机ip变了，需重新匹配步骤数')

        self.total_step = total_step

    def get_frame_callback(self):
        # if safeCame_obj == None:
        #     raise Exception('')
        if self.triggermode == 'hard':
            def frame_callback(img):
                # while self.hit_int == 1: #
                #     pass
                print(f'ip {self.ip0} 已获取图像 {self.numb}')
                self.imgs_queue.put(img) # 图像和步骤 todo 同步
                self.numb = (self.numb) % self.total_step + 1
                if self.hit_int == 1:
                    raise Exception('生产速度高于消费速度')
                else:
                    self.hit_int = 1
            return frame_callback
        else:
            return None
    def get_trigger_signal(self,var_name=''): # 获取触发
        return self.hit_int

    def set_zero_trigger_signal(self,var_name=''): # 置0
        self.hit_int = 0

    def get_step_mode(self, var_name=''):
        return self.numb # 1 2 3

    def open(self, ip0, triggermode='off', frame_callback=None):
        if ip0 is not None:
            self.ip0 = ip0
            self.triggermode = triggermode
            self.frame_callback = frame_callback
            if frame_callback is None:
                self.cam = self.cls(ip0)
            else:
                self.cam = self.cls(ip0, triggermode, frame_callback)
            return 1

        return 0

    def close(self):
        if self.cam is not None:
            self.cam.close()
        return 0

    def getFrame(self, ExposureTime=0):
        im = None
        if self.triggermode == 'hard':
            im = self.imgs_queue.get() # 阻塞
            # if self.hit_int == 0
            # im = self.current_img
        else:
            for i in range(100):
                im = self.cam.getFrame(ExposureTime=ExposureTime)
                if im is not None:
                    return im
            # if random.random()>0.5:
            #    im = None
            if im is None:
                print('SafeCam: cam reopen')
                self.close()
                self.cam = None
                self.open(self.ip0, self.triggermode, self.frame_callback)
                im = self.cam.getFrame()

        return im

    def set_exposure_time(self, et=0):
        self.cam.setExposureTime(et)


class CamFactory: #
    @staticmethod
    def create(class_type, ip='127.0.0.1',total_step=15):
        if class_type == "basler":
            return SafeCam(BaslerCam, ip)

        elif class_type == "mvs":
            from camera.MVSCam.MVSCam_class import MVSCam
            return SafeCam(MVSCam, ip,total_step=total_step)

        elif class_type == "mvs_hard":
            from camera.MVSCam.MVSCam_class import MVSCam
            return SafeCam(MVSCam, ip, triggermode='hard',total_step=total_step)

        elif class_type == "mvs_line":
            return SafeCam(MVSLineCam, ip) # 线扫相机

        elif class_type == "sim":
            from camera.sim_camera import SimCamera as SimCam
            return SafeCam(SimCam, ip, total_step=total_step) # from get_config import pp, pp存放图片目录
        elif class_type == "sim_hard":
            from camera.sim_camera import SimCamera as SimCam
            return SafeCam(SimCam, ip, triggermode='hard', total_step=total_step)

        else:
            raise ValueError("Invalid transport type")
